<!--
 * @Author: 赵克强 huohuo625@163.com
 * @Date: 2023-11-07 11:31:40
 * @LastEditors: 赵克强 huohuo625@163.com
 * @LastEditTime: 2025-04-16 09:42:13
 * @FilePath: \hy-ui\src\views\render\components\pagerTable.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<!--
 * @Author: 赵克强 huohuo625@163.com
 * @Date: 2023-11-07 11:31:40
 * @LastEditors: 赵克强 huohuo625@163.com
 * @LastEditTime: 2023-11-07 14:45:27
 * @FilePath: \hy-ui\src\views\render\components\pagerTable.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
  <div class="pagerTable">
    <el-table ref="multipleTable" :data="tableData.rows" border style="width: 100%"
      @selection-change="handleSelectionChange" row-key="id"
      :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" @sort-change="sortChange" size="mini">
      <!-- show-summary
      :summary-method="getSummaries" -->
      <el-table-column type="selection" width="55" v-if="tableColumns.checkBox === 'C'" align="center" fixed="left">
      </el-table-column>
      <el-table-column v-if="tableColumns.checkBox === 'R'" align="center" width="55" fixed="left">
        <template slot-scope="scope">
          <el-radio v-model="radio" :label="scope.$index" @change.native="getCurrentRow(scope.row)">&nbsp;
          </el-radio>
        </template>
      </el-table-column>
      <el-table-column :prop="item.name" :label="item.label" :customSum="item.name" :width="item.label === '序号' ? 50 : item.width ? item.width : undefined
        " v-for="item in tableColumns.columns" :key="item.name" :show-overflow-tooltip="item.label !== '操作'" :align="item.label === '操作'
    ? 'center'
    : isLeft
      ? 'left'
      : item.align || 'center'
    " :fixed="isFixed(item)" :sortable="item.label !== '操作' &&
    item.label !== '序号' &&
    item.sortable === 'NO' &&
    item.type !== 'dic'
    ">
        <template slot="header" v-if="item.type === 'dic' && item.sortable === 'NO'">
          <div style="display: flex; justify-content: center">
            <span style="display: flex; align-items: center"><span>{{ item.label }}</span><el-dropdown trigger="click"
                @command="(val) => handleStatusChange(val, item.name)">
                <div>
                  <svg style="cursor: pointer" t="1722218323622" viewBox="0 0 1024 1024" version="1.1"
                    xmlns="http://www.w3.org/2000/svg" p-id="4536" width="20" height="20">
                    <path
                      d="M872.533333 134.4c-12.8-10.666667-29.866667-17.066667-49.066666-17.066667H198.4C157.866667 117.333333 123.733333 151.466667 123.733333 192c0 17.066667 6.4 34.133333 17.066667 49.066667l256 302.933333v251.733333c0 12.8 6.4 23.466667 17.066667 27.733334l162.133333 81.066666c4.266667 2.133333 8.533333 4.266667 14.933333 4.266667 6.4 0 10.666667-2.133333 17.066667-4.266667 8.533333-6.4 14.933333-17.066667 14.933333-27.733333V541.866667l256-302.933334c12.8-14.933333 19.2-34.133333 17.066667-53.333333 2.133333-19.2-6.4-38.4-23.466667-51.2z m-38.4 64L569.6 509.866667c-4.266667 6.4-8.533333 12.8-8.533333 21.333333v292.266667l-98.133334-49.066667V531.2c0-8.533333-2.133333-14.933333-8.533333-21.333333L189.866667 198.4c0-2.133333-2.133333-4.266667-2.133334-6.4 0-6.4 4.266667-10.666667 10.666667-10.666667h625.066667c2.133333 0 4.266667 0 6.4 2.133334 2.133333 2.133333 4.266667 6.4 4.266666 6.4 2.133333 2.133333 2.133333 6.4 0 8.533333z"
                      fill="#1296db" p-id="4537"></path>
                  </svg>
                  <el-dropdown-menu slot="dropdown" style="text-align: center">
                    <el-dropdown-item command="">全部</el-dropdown-item>
                    <el-dropdown-item v-for="(x, i) in dictData[item.format]" :key="i" :command="x.dictValue">{{
                      x.dictLabel }}</el-dropdown-item>
                  </el-dropdown-menu>
                </div>
              </el-dropdown></span>
          </div>
        </template>
        <template slot-scope="scope">
          <div v-if="item.label === '操作' && item.buttons">
            <span v-for="(v, i) in item.buttons" :key="i">
              <el-button size="mini" type="text" class="tableBtn" v-if="hasPermissions(v)"
                :style="{ color: getBtnColor(v) }" @click="() => handleLineOperate(scope.row, v)"
                :disabled="isDisabled(v, scope.row)"><svg-icon :icon-class="v.icon" style="margin-right: 3px" />{{
                  v.label
                }}</el-button>
            </span>
          </div>
          <span v-if="item.type === 'date'">{{
            formatDate(scope.row[item.name], item.format)
          }}</span>
          <span v-else-if="item.type === 'datetime'">{{
            formatDateTime(scope.row[item.name], item.format)
          }}</span>
          <span v-else-if="item.type === 'dic'">{{
            forMatDictLabel(dictData[item.format], scope.row[item.name])
          }}</span>
          <span v-else-if="item.type === 'user'">{{
            scope.row[`${item.name}Desc`]
          }}</span>
          <span v-else-if="item.type === 'dept'">{{
            scope.row[`${item.name}Desc`]
          }}</span>
          <span v-else-if="item.type === 'custom'">{{
            formatCustom(item.name, scope.row[item.name], item.format)
          }}</span>
          <span v-else-if="item.type === 'customModel'">{{
            formatCustomModel(scope.row[item.name])
          }}</span>
          <span v-else-if="item.type === 'customLogic'">{{
            getDataCustomLogic(scope.row[item.name], item.format)
          }}</span>

          <span v-else-if="item.type === 'file'" style="display:inline-block;width:100%">
            <p v-for="val in formatFile('file', scope.row[item.name])" :key="val.url"
              style="margin: 0; cursor: pointer; color: #409eff;width:100%;display:flex;align-items:center">
              <span @click="handleFileClick(val)"
                style="display:inline-block;width:90%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis">{{
                  val.name }}</span>
              <i class="el-icon-download" style="margin-left: 10px" @click="handleFileDownload(val)"></i>
            </p>
          </span>
          <span v-else-if="item.type === 'image'"><el-image style="width: 50px; height: 50px"
              v-for="val in formatFile('image', scope.row[item.name])" :key="val.url" :src="val.url"
              :preview-src-list="[val.url]">
            </el-image></span>
          <span v-else-if="item.name === 'processStatus'">{{
            scope.row[item.name] === "1" ? "已提交" : scope.row[item.name] === "0" ? "草稿" : scope.row[item.name] === "2" ?
              '已完成' : '--'
          }}</span>
          <span v-else>{{ scope.row[item.name] }}</span>
        </template>
      </el-table-column>
    </el-table>
    <div class="pagination" v-if="searchJson.footerToolbar">
      <pagination v-show="total > 0" :page-sizes="searchJson.perPageAvailable" :total="total"
        :page.sync="queryParams.page" :limit.sync="queryParams.perPage" @pagination="getList" />
    </div>
  </div>
</template>

<script>
import { FormDelete, getFlowDetailPath } from "@/api/render/pager.js";
import moment from "moment";
import request from "@/utils/request";
import { EventBus } from '@/utils/eventBus';

export default {
  name: "HyUiPagerTable",
  props: {
    searchJson: {
      type: Object,
      default: () => { },
    },
    tableColumns: {
      type: Object,
      default: () => { },
    },
    getList: {
      type: Function,
      default: () => { },
    },
    tableData: {
      type: Object,
      default: () => { },
    },
    openModal: {
      type: Function,
      default: () => { },
    },
    openZbModal: {
      type: Function,
      default: () => { },
    },
    dictData: {
      type: Object,
      default: () => { },
    },
    interfaceList: {
      type: Object,
      default: () => { },
    },
    isLeft: {
      type: Boolean,
      default: false,
    },
    zbDisplayButton: {
      type: String,
      default: "",
    },
    zbCount: {
      type: Number,
      default: 0,
    },
  },
  data() {
    return {
      radio: undefined,
      chooseBox: [],
      chooseRadio: {},
      total: 0,
      queryParams: {
        perPage: 10,
        page: 1,
      },
    };
  },

  mounted() {
    this.total = this.tableColumns?.count;
    this.queryParams = {
      ...this.queryParams,
      perPage: this.tableColumns?.params?.perPage,
      page: this.tableColumns?.params?.page,
    };
    if (this.zbDisplayButton === "2") {
      this.tableColumns.columns.splice(
        this.tableColumns.columns?.length - 1,
        1
      );
    }
  },
  watch: {
    zbCount() {
      this.total = this.zbCount;
    },
  },
  methods: {
    getDataCustomLogic(value, logic) {
      const data = new Function("value", logic)(value);
      return data;
    },
    // getSummaries(param) {
    //  const { columns, data } = param;
    //     const sums = [];
    //     columns.forEach((column, index) => {
    //       if (index === 0) {
    //         sums[index] = '总价';
    //         return;
    //       }
    //       const values = data.map(item => Number(item[column.property]));
    //       if (!values.every(value => isNaN(value))) {
    //         sums[index] = values.reduce((prev, curr) => {
    //           const value = Number(curr);
    //           if (!isNaN(value)) {
    //             return prev + curr;
    //           } else {
    //             return prev;
    //           }
    //         }, 0);
    //         sums[index] += ' 元';
    //       } else {
    //         sums[index] = 'N/A';
    //       }
    //     });

    //     return sums;
    // },
    formatCustomModel(val) {
      try {
        return JSON.parse(val).names;
      } catch (error) {
        console.log(error);
        return "";
      }
    },
    formatCustom(key, value, formatObj) {
      const list = this.interfaceList[key];
      if (value?.includes(",")) {
        const valArr = value.split(",");
        const labelArr = [];
        list.forEach((item) => {
          valArr.forEach((x) => {
            if (x === item[formatObj.saveField]) {
              labelArr.push(item[formatObj.displayField]);
            }
          });
        });
        return labelArr.toString();
      } else {
        const filterData = list?.filter(
          (item) => item[formatObj.saveField] === value
        );
        if (filterData?.length) {
          return filterData[0][formatObj.displayField];
        } else {
          return value || "--";
        }
      }
    },
    resetData() {
      this.queryParams = {
        perPage: this.tableColumns?.params?.perPage,
        page: this.tableColumns?.params?.page,
      };
    },
    handleStatusChange(val, type) {
      this.queryParams[type] = val;
      this.getList();
    },
    sortChange(col) {
      if (this.queryParams.orderBy || this.queryParams.orderDir) {
        delete this.queryParams.orderBy;
        delete this.queryParams.orderDir;
      }
      if (col.order === "ascending") {
        this.queryParams.orderBy = col.prop;
        this.queryParams.orderDir = "asc";
      } else if (col.order === "descending") {
        this.queryParams.orderBy = col.prop;
        this.queryParams.orderDir = "desc";
      }
      this.getList();
    },
    totalNum(val) {
      this.total = val;
    },
    isDisabled(config, row) {
      if (
        (config.buttonType === "handleDetailFlow" &&
          row.processStatus === "0") || (config.buttonType === "processEdit" &&
            row.processStatus !== "0") || (config.buttonType === "handleDel" && row.processStatus &&
              row.processStatus !== "0")
      ) {
        return true;
      }

      return false;
    },
    formatDate(value, type) {
      let formatType = "";
      if (type.includes("dd")) {
        formatType = type.replace("dd", "DD");
      }
      if (value && type) {
        return moment(value).format(formatType);
      }
      return value || "--";
    },
    formatDateTime(value,type){
      let formatType = "";
      if (type.includes("dd")) {
        formatType = type.replace("dd", "DD");
      }
      if (value && type && value.includes(',')) {
        const data = value.split(',')
        return `${moment(data[0]).format(formatType)} - ${moment(data[1]).format(formatType)}`;
      }
      return value || "--";
    },
    handleFileDownload(row) {
      const a = document.createElement("a");
      a.href = row.url;
      a.download = row.name;
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
    },
    handleFileClick(row) {
      if (row.name.includes(".pdf")) {
        window.open(row.url);
      }
    },
    formatFile(type, data) {
      if (data) {
        const list = JSON.parse(data);
        if (list?.length) {
          return list;
        }
        return [];
      }
      return [];
    },
    hasPermissions(val) {
      if (!!val.permissions) {
        let ispass = false;
        this.$store.state.user.roles?.forEach((item) => {
          if (JSON.parse(val.permissions).includes(item)) {
            ispass = true;
          }
        });
        return ispass;
      } else {
        return true;
      }
    },
    forMatDictLabel(datas, value) {
      if (value && datas.length) {
        if (value.includes(',')) {
          const list = value.split(',')
          const data = []
          datas.forEach(item => {
            if (list.length && list.includes(item.dictValue)) {
              data.push(item.dictLabel)
            }
          })
          return data.length ? data.toString() : '--'
        } else {
          const data = datas?.filter((item) => item.dictValue === value);
          if (data) {
            return data[0]?.dictLabel;
          } else {
            return value;
          }
        }



      }
      return value;
    },
    handleSelectionChange(arr) {
      this.chooseBox = arr;
      EventBus.$emit('chooseArr', { data:this.chooseBox });
    },
    getCurrentRow(key) {
      this.chooseRadio = key;
      EventBus.$emit('chooseArr', { data:[this.chooseRadio] });
    },
    replaceUrlPlaceholders(url, values) {
      return url.replace(/\{([^}]+)\}/g, (match, key) => {
        const value = values[key];
        return value ? encodeURIComponent(value) : "";
      });
    },
    async handleLineOperate(row, item) {
      if (item.buttonType === "handleDel") {
        if (item.actionType === "ajax") {
          let resRule = undefined;
          if (!!item.optJs) {
            resRule = await request({
              url: item.optJs,
              method: "post",
              data: { id: row.id },
            });
          }
          if (!!item.optJs && resRule.code !== 200) {
            return this.$message.error(resRule.msg);
          }
          this.$confirm(item?.confirmText || "确认该操作吗？", "提示", {
            confirmButtonText: "确定",
            cancelButtonText: "取消",
            type: "warning",
          })
            .then(async () => {
              const res = await FormDelete(item.tooltip, row.id);
              if (res.code === 200) {
                this.$message.success(`${item.label}成功`);
                this.getList();
              }
            })
            .catch(() => { });
        }
      }
      if (item.buttonType === "handleEdit") {
        if (item.actionType === "form") {
          this.openModal(item, row);
        } else if (item.actionType === "page") {
          // TODO
        }
      }
      if (item.buttonType === "handleDetailFlow") {
        if (item.actionType === "page") {
          const res = await getFlowDetailPath(item.tooltip, { id: row.id });
          if (res.code === 200) {
            this.$router.push({
              path: res.msg,
            });
          }
        } else if (item.actionType === "form") {
          // TODO
        }
      }
      if (item.buttonType === "zb") {
        if (item.actionType === "form") {
          this.openZbModal(item, row);
        } else if (item.actionType === "page") {
          // TODO
        }
      }
      if (item.buttonType === "handleDetail") {
        if (item.actionType === "form") {
          this.openModal(item, row);
        } else if (item.actionType === "page") {
          // TODO
        }
      }
      if (item.buttonType === "report") {
        window.open(
          `${process.env.VUE_APP_BASE_API}/ureport/pdf/show?_u=file:${item.tooltip}&_p=1&id=${row.id}`
        );
      }
      if (item.buttonType === "processEdit") {
        this.$router.push({
          path: `${item.tooltip}&id=${row.id}`,
        });
      }
      if (item.buttonType === "handleExt") {
        if (item.zdyLxb === "1") {
          this.$router.push({
            path: this.replaceUrlPlaceholders(item.optJs, row),
          });
        } else if (item.zdyLxb === "2") {
          window.open(item.optJs);
        } else if (item.zdyLxb === "3") {
          if (item.optJs) {
            const url = this.replaceUrlPlaceholders(item.optJs, row);
            const res = await request({
              url,
              method: "get",
            });
            if (res.code === 200) {
              this.$message.success("操作成功！");
              this.getList();
            }
          }
        }
      }
    },
    isFixed(item) {
      if (item.label === "操作") {
        if (item.fixed === "YES") {
          return "right";
        } else {
          return false;
        }
      } else {
        if (item.fixed === "none" || !item.fixed) {
          return false;
        } else {
          return item.fixed;
        }
      }
    },
    getBtnColor(val) {
      const colorMapping = {
        danger: "#f56c6c",
        info: "#909399",
        warning: "#e6a23c",
        success: "#67c23a",
      };
      return colorMapping[val.level] ? colorMapping[val.level] : "#409eff";
    },
  },
};
</script>

<style lang="scss" scoped>
.pagerTable {
  margin-top: 8px;

  ::v-deep .el-radio__label {
    display: none;
  }

  .pagination {
    display: flex;
    justify-content: flex-end;
    // margin-top: 20px;
  }

  .tableBtn {
    margin-right: 5px;
  }

  ::v-deep .el-dropdown {
    display: flex;
    align-items: center;
  }

}
</style>
